package com.plumecache.core.compressor;

import lombok.SneakyThrows;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class GzipCacheCompressor implements CacheCompressor {
    
    @SneakyThrows
    @Override
    public String compress(String value) {
        if (value == null || value.length() == 0) {
            return value;
        }

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzip = null;

        try {
            gzip = new GZIPOutputStream(out);
            gzip.write(value.getBytes());
        } finally {
            if (gzip != null) {
                gzip.close();
            }
        }

        return new sun.misc.BASE64Encoder().encode(out.toByteArray());
    }


    @SneakyThrows
    @Override
    public String decompress(String value) {
        if (value == null) {
            return null;
        }

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ByteArrayInputStream byteArrayInputStream = null;
        GZIPInputStream gzipInputStream = null;
        byte[] compressed;
        String decompressed;
        try {
            compressed = new sun.misc.BASE64Decoder().decodeBuffer(value);
            byteArrayInputStream = new ByteArrayInputStream(compressed);
            gzipInputStream = new GZIPInputStream(byteArrayInputStream);

            byte[] buffer = new byte[1024];
            int offset;
            while ((offset = gzipInputStream.read(buffer)) != -1) {
                byteArrayOutputStream.write(buffer, 0, offset);
            }
            decompressed = byteArrayOutputStream.toString();
        } finally {
            if (gzipInputStream != null) {
                gzipInputStream.close();
            }

            if (byteArrayInputStream != null) {
                byteArrayInputStream.close();
            }

            byteArrayOutputStream.close();
        }

        return decompressed;
    }
}
